/**
* @program: src
*
* @description:群管理
*
* @author: Mr.chen
*
* @create: 2020-11-20 15:26
**/
package models

import (
	mydb "ydd-im/service/api/tools/mysql/conn"
	"ydd-im/service/api/tools/util"
	"database/sql"
	"errors"
	"fmt"
	"github.com/jmoiron/sqlx"
	"strings"

	"time"
)

type Group struct {
	Id            int       `db:"id" json:"id"`
	Name          string    `db:"name" json:"name"`
	Ownerid       int       `db:"ownerid" json:"ownerid"`
	GroupKey      string    `db:"groupkey" json:"groupkey"`
	Icon          string    `db:"icon" json:"icon"` //创建时间
	Cate          int       `db:"cate" json:"-"`
	Memo          string    `db:"memo" json:"-"`
	Createtime    time.Time `db:"createtime" json:"-"`
	Createtimestr string    `db:"createtimestr" json:"createtime"`
	IsInGroup     int       `db:"isingroup" json:"isingroup"`
}

//orm 回调
func (g *Group) TableName() string {
	return TNGroup()
}

func NewGroup() *Group {
	return &Group{}
}

// 添加群
func (g *Group) AddGroup(group *Group) (insertid int64, err error) {
	sqlStr := "insert  into " + g.TableName() + "(name,ownerid,groupkey,icon,cate,memo,createtime) values (?,?,?,?,?,?,?)"
	dbconn,err := mydb.DBConn("")
	if err != nil {
		return 0, err
	}
	ret, err := dbconn.Exec(sqlStr, group.Name, group.Ownerid, group.GroupKey, group.Icon, group.Cate, group.Memo, group.Createtime)
	if err != nil {
		return 0, err
	}
	theID, err := ret.LastInsertId() // 新插入数据的id
	if err != nil {
		return 0, err
	}
	return theID, nil
}
/**
 * 添加群
 * @access  public
 * @param   Group     group     群结构体
 * @return int64 insertid   自增id
 * @return  error  err  错误信息
 */
func (g *Group) AddGroupTx(group *Group,tx *sqlx.Tx) (insertid int64, err error) {
	sqlStr := "insert  into " + g.TableName() + "(name,ownerid,groupkey,icon,cate,memo,createtime) values (?,?,?,?,?,?,?)"
	ret, err := tx.Exec(sqlStr, group.Name, group.Ownerid, group.GroupKey, group.Icon, group.Cate, group.Memo, group.Createtime)
	if err != nil {
		return 0, err
	}
	theID, err := ret.LastInsertId() // 新插入数据的id
	if err != nil {
		return 0, err
	}
	return theID, nil
}
/**
 * 获取群记录
 * @access  public
 * @param   int     sid     签名所属Id
 * @param   int     userid   用户id
 * @return  []slice group   群列表
 * @return  error  err  错误信息
 */
func (g *Group) GetAllGroupJoinGroupContactList(sid, userid int) (group []Group, err error) {
	group = []Group{}
	u := &User{}
	gc := &GroupContact{}
	var where []string
	if sid > 0 {
		where = append(where, fmt.Sprintf("b.sid = %d", sid))
	}
	sqlStr := "select a.id, a.name,a.ownerid,a.icon,DATE_FORMAT(a.createtime, '%Y-%m-%d %T') as createtimestr,if((select count(id) from " + gc.TableName() + " where ownerid = ? and dstid = a.id and cate = 0 ) > 0,1,0) as isingroup from " + g.TableName() + " as a inner join " + u.TableName() + " as b on a.ownerid = b.id"
	if len(where) > 0 {
		whereStr := fmt.Sprintf(" WHERE %s", strings.Join(where, " AND "))
		isok := util.FilteredSQLInject(whereStr)
		if (isok) {
			return group, errors.New("参数有误，请重试！")
		}
		sqlStr += whereStr
	}
	sqlStr += " order by a.id asc"
	//fmt.Println(sqlStr)
	dbconn,err := mydb.DBConn("r")
	if err != nil {
		return group, err
	}
	err = dbconn.Select(&group, sqlStr, userid)
	if err == sql.ErrNoRows { // 为空
		return group, nil
	}
	if err != nil {
		return group, err
	}
	return group, nil
}

/**
 * 查询群信息
 * @access  public
 * @param   []string     where     条件
 * @param   string     field   获取的列
 * @param   string     orderby   排序
 * @param   string     orderby   排序
 * @return  Group   group   群列表
 * @return  error  err  错误信息
 */
func (g *Group) GetGroupJoinUserInfo(where []string, field string, orderby string, on string, ischeck bool) (group Group, err error) {
	group = Group{}
	u := &User{}
	if len(field) == 0 {
		field = "a.id"
	}
	if len(on) == 0 {
		on = " a.ownerid = b.id "
	}
	sqlStr := "select " + field + " from " + g.TableName() + " as a inner join " + u.TableName() + " as b  on " + on
	if len(where) > 0 {
		whereStr := fmt.Sprintf(" WHERE %s", strings.Join(where, " AND "))
		if ischeck {
			isok := util.FilteredSQLInject(whereStr)
			if (isok) {
				return group, errors.New("参数不合法，请重试！")
			}
		}
		sqlStr += whereStr
	}
	if len(orderby) == 0 {
		sqlStr += " order by a.id asc"
	} else {
		sqlStr += " " + orderby
	}

	dbconn,err := mydb.DBConn("r")
	if err != nil {
		return group, err
	}
	err = dbconn.Get(&group, sqlStr)
	if err == sql.ErrNoRows { // 为空
		return group, nil
	}
	if err != nil {
		return group, err
	}
	return group, nil
}
// 事务操作 / db.Beginx()
func (g *Group) transactionDemo2()(err error) {
	// 开启事务
	dbconn,err := mydb.DBConn("w")
	tx, err := dbconn.Beginx()
	if err != nil {
		fmt.Printf("begin trans failed, err:%v\n", err)
		return err
	}

	defer func() {
		// 捕获panic
		if p := recover(); p != nil {
			// 回滚
			tx.Rollback()
			panic(p) // re-throw panic after Rollback
		} else if err != nil {
			fmt.Println("rollback")
			tx.Rollback() // err is non-nil; don't change it
		} else {
			err = tx.Commit() // err is nil; if Commit returns error update err
			fmt.Println("commit")
		}
	}()

	// 更新语句1
	sqlStr1 := "Update chat_group set name=18 where id=?"

	rs, err := tx.Exec(sqlStr1, 30)
	if err!= nil{
		return err
	}
	n, err := rs.RowsAffected() // 影响行数
	if err != nil {
		return err
	}


	if n != 1 {
		return errors.New("exec sqlStr1 failed")
	}

	// 更新语句2
	sqlStr2 := "Update chat_group set name=99 where i=?"

	rs, err = tx.Exec(sqlStr2, 5)
	if err!=nil{
		return err
	}
	n, err = rs.RowsAffected() // 影响行数
	if err != nil {
		return err
	}
	if n != 1 {
		return errors.New("exec sqlStr1 failed")
	}
	return err
}